package cn.wjssl.domain.activity.repository;

import cn.wjssl.domain.activity.model.aggregate.CreatePartakeOrderAggregate;
import cn.wjssl.domain.activity.model.aggregate.CreateQuotaOrderAggregate;
import cn.wjssl.domain.activity.model.entity.*;
import cn.wjssl.domain.activity.model.valobj.ActivitySkuStockKeyVO;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 活动仓储接口
 */
public interface IActivityRepository {

    // 根据sku, 查询活动商品sku实体
    ActivitySkuEntity queryActivitySku(Long sku);

    // 根据活动id, 查询活动实体, 优先走redis
    ActivityEntity queryRaffleActivityByActivityId(Long activityId);

    // 根据活动次数, 查询活动次数实体, 优先走redis
    ActivityCountEntity queryRaffleActivityCountByActivityCountId(Long activityCountId);

    // 通过事务, 将订单聚合对象拆分, 更新activity_order表和account表
    void doSaveSkuOrder(CreateQuotaOrderAggregate createQuotaOrderAggregate);

    // 存入无需支付的sku单
    void doSaveNoPayOrder(CreateQuotaOrderAggregate createQuotaOrderAggregate);

    // 存入需要支付的sku单
    void doSaveCreditPayOrder(CreateQuotaOrderAggregate createQuotaOrderAggregate);

    // 缓存活动SKU初始库存
    void cacheActivitySkuStockCount(String cacheKey, Integer stockCount);

    // 更新库存, 并加库存锁
    boolean subtractionActivitySkuStock(Long sku, String cacheKey, Date endDateTime);

    // 把扣减库存对应的SKU放入redis延迟队列, 等待定时任务消费
    void activitySkuStockConsumeSendQueue(ActivitySkuStockKeyVO activitySkuStockKeyVO);

    // 弹出sku的redis队列中的第一个, 用于同步消耗数据库库存
    ActivitySkuStockKeyVO takeQueueValue();

    ActivitySkuStockKeyVO takeQueueValue(Long sku);

    // 同步更新Mysql中的库存
    void updateActivitySkuStock(Long sku);

    // 缓存库存以消耗完毕，直接更新数据库库存为0
    void clearActivitySkuStock(Long sku);

    // 清空redis的延迟队列
    void clearQueueValue();

    // 查询未使用的订单
    UserRaffleOrderEntity queryNoUsedRaffleOrder(PartakeRaffleActivityEntity partakeRaffleActivityEntity);

    // 通过事务, 将聚合对象拆分, 更新user_order表, account表, account_day表, account_month表
    void saveCreatePartakeOrderAggregate(CreatePartakeOrderAggregate createPartakeOrderAggregate);

    // 根据userId, activityId 查询 account
    ActivityAccountEntity queryActivityAccountByUserId(String userId, Long activityId);

    // 根据userId, activityId, month 查询 accountMonth
    ActivityAccountMonthEntity queryActivityAccountMonthByUserId(String userId, Long activityId, String month);

    // 根据userId, activityId, day 查询 accountDay
    ActivityAccountDayEntity queryActivityAccountDayByUserId(String userId, Long activityId, String day);

    // 根据activityId, 查询商品sku列表
    List<ActivitySkuEntity> queryActivitySkuListByActivityId(Long activityId);

    // 获取用户 [当日] 抽奖次数, 根据activityId, userId 查询 account_day表 相减获得用户当日已抽奖次数
    Integer queryRaffleActivityAccountDayPartakeCount(Long activityId, String userId);

    // 根据activityId, userId 查询account表, 获取用户总账户信息
    ActivityAccountEntity queryActivityAccountEntity(Long activityId, String userId, String day, String month);

    // 查询用户 [当前总共] 抽奖次数, 根据activityId, userId 查询 account表 相减获得用户总共已抽奖次数
    Integer queryRaffleActivityAccountTotalPartakeCount(Long activityId, String userId);

    // 通过userId, outBusinessNo, 查询sku单, 更新sku单, 并更新总账户, 月账户, 日账户
    void updateOrder(DeliveryOrderEntity deliveryOrderEntity);

    // 根据activityId 查询sku表, 获取sku商品列表
    List<SkuProductEntity> querySkuProductEntityListByActivityId(Long activityId);

    // 根据 userId, 查询积分账户余额
    BigDecimal queryUserCreditAccountAmount(String userId);

    // 查询所有sku商品的sku编号
    List<Long> querySkuList();
}
